package com.captcha.config;

import com.captcha.exception.ConfigException;

import java.awt.*;
import java.lang.reflect.Field;

/**
 * @Author: 随风飘的云
 * @Description: 配置方法灵感来源于Kaptcha，
 *              详情请查看：https://github.com/penggle/kaptcha
 * @Date: 2022/3/4 18:46
 * @Modified By:
 */
public class ConfigHelper {

    /**
     * 获取颜色
     * @param paramName
     * @param paramValue
     * @param defaultColor
     * @return
     */
    public Color getColor(String paramName, String paramValue, Color defaultColor){
        Color color;
        if("".equals(paramValue) || paramValue == null){
            color = defaultColor;
        } else {
            color = createColor(paramName, paramValue);
        }
        return color;
    }

    /**
     * 创建颜色
     * @param paramName
     * @param paramValue
     * @return
     */
    private Color createColor(String paramName, String paramValue){
        Color color;
        try {
            if(paramValue.indexOf(",") > 0){
               paramValue = paramValue.replaceAll(" ", "");
                String[] rgb = paramValue.split(",");
                int r = Integer.parseInt(rgb[0]);
                int g = Integer.parseInt(rgb[1]);
                int b = Integer.parseInt(rgb[2]);
                if(rgb.length == 4){
                    int a = Integer.parseInt(rgb[3]);
                    color = new Color(r,g,b,a);
                }else if(rgb.length == 3){
                    color = new Color(r,g,b);
                } else {
                    throw new ConfigException(paramName, paramValue,
                            "The color need rgb which can only have 3(RGB) or 4 (RGB with Alpha) values");
                }
            } else {
                color = new Color(Integer.valueOf(paramValue, 16));
            }
        } catch (Exception e) {
            throw new ConfigException(paramName, paramValue, e);
        }
        return color;
    }

    /**
     * 通过反射设置配置起作用的类
     * @param paramName
     * @param paramValue
     * @param defaultClass
     * @param config
     * @return
     */
    public Object getClassInstance(String paramName, String paramValue, Object defaultClass, Config config){
        Object instance;
        if(paramValue == null){
            instance = defaultClass;
        }else {
            try {
                instance = Class.forName(paramValue).newInstance();
            } catch (Exception e){
                throw new ConfigException(paramName, paramValue, e);
            }
        }
        setConfigurable(instance, config);
        return instance;
    }

    /**
     * 获取字体（设置的字体全部为windows10系统内部自带的字体）
     * @param paramName
     * @param paramValue
     * @param fontSize
     * @param defaultFont
     * @return
     */
    public Font[] getTextFont(String paramName, String paramValue, int fontSize, Font[] defaultFont){
        Font[] fonts;
        if(paramValue == null || paramValue.length() == 0){
            fonts = defaultFont;
        } else {
            try {
                String[] fontNames = paramValue.split(",");
                int len = fontNames.length;
                fonts = new Font[len];
                for (int i = 0; i < len; i++) {
                    fonts[i] = new Font(fontNames[i], Font.PLAIN, fontSize);
                }
            }catch (Exception e){
                throw new ConfigException(paramName, paramValue,
                        "The program cannot set the font, please check the program and reset");
            }
        }
        return fonts;
    }

    /**
     *  设置长度，数字，比如说验证码的宽度，长度，字符长度，干扰线长度。
     * @param paramName
     * @param paramValue
     * @param defaultInt
     * @return
     */
    public int setPositiveInt(String paramName, String paramValue, int defaultInt) {
        int intValue;
        if(paramValue == null || paramValue.length() == 0){
            intValue = defaultInt;
        }else {
            try {
                intValue = Integer.valueOf(paramValue);
                if(intValue < 0){
                    throw new ConfigException(paramName, paramValue,
                            "The metric you set is not appropriate, please set it again");
                }
            } catch (NumberFormatException e){
                throw new ConfigException(paramName, paramValue, e);
            }
        }
        return intValue;
    }

    /**
     * 设置验证码图片内容格式和图片格式
     * @param paramName
     * @param paramValue
     * @param defaultType
     * @param checkType
     * @return
     */
    public String setType(String paramName, String paramValue, String defaultType, String checkType){
        String type = null;
        boolean check = false;
        if(paramValue == null || paramValue.length() == 0){
            type = defaultType;
        }else {
            paramValue = paramValue.toUpperCase();
            String[] value = checkType.split(",");
            int len = value.length;
            for (int i = 0; i < len; i++) {
                if(paramValue.equals(value[i])){
                    type = value[i];
                    check = true;
                    break;
                }
            }
            if(!check){
                throw new ConfigException(paramName, paramValue,
                        "The content format set by the user does not meet the requirements, please reset");
            }
        }
        return type;
    }

    /**
     * 设置是否需要
     * @param paramName
     * @param paramValue
     * @param defaultBoolean
     * @return
     */
    public boolean setBoolean(String paramName, String paramValue, boolean defaultBoolean){
        boolean value;
        if(paramValue == null|| paramValue.length() == 0){
            value = defaultBoolean;
        }else {
            paramValue = paramValue.toLowerCase();
            if(paramValue.equals("yes")){
                value = defaultBoolean;
            }else if(paramValue.equals("no")){
                value = false;
            }else {
                throw new ConfigException(paramName, paramValue, "Must be set to YES or NO and not case sensitive");
            }
        }
        return value;
    }
    /**
     * 设置配置
     * @param object
     * @param config
     */
    private void setConfigurable(Object object, Config config){
        if(object instanceof Configurable){
            ((Configurable) object).setConfig(config);
        }
    }
}
